package com.example.stock.util;

import com.example.stock.vo.DataVo;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: zhuchunfeng
 * @Description
 * @Date: 2021/1/2 14:15
 * Copyright (c) 2019 北京新媒传信科技有限公司
 */
public class CalcUtil {

    /**
     * 计算总金额
     * @param from
     * @param to
     */
    public static BigDecimal sumAmount(List<DataVo> list, int from, int to) {
        List<DataVo> doubles = list.subList(from, to + 1);
        BigDecimal ret = BigDecimal.ZERO;
        for (DataVo aDouble : doubles) {
            ret = ret.add(aDouble.getBigDecimal());
        }
        return  ret;
    }

    public static List<DataVo> REF(List<DataVo> closeData,int n) {
        List<DataVo> ret = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            ret.add(closeData.get(i));
        }
        for (int i = n; i < closeData.size(); i++) {
            DataVo cur = closeData.get(i);
            DataVo vo = new DataVo(cur.getTime(), closeData.get(i-n).getBigDecimal());
            ret.add(vo);
        }
        return ret;
    }

    public static List<DataVo> EMA(List<DataVo> list, int number) {
        List<DataVo> doubles = new ArrayList<>();
        BigDecimal k = new BigDecimal("2").divide(new BigDecimal(number + 1.0), 4, RoundingMode.HALF_UP);
        // 第一天ema等于当天收盘价
        BigDecimal ema = list.get(0).getBigDecimal();
        doubles.add(new DataVo(list.get(0).getTime(),ema));
        for (int i = 1; i < list.size(); i++) {
            // 第二天以后，当天收盘 收盘价乘以系数再加上昨天EMA乘以系数-1
            ema = list.get(i).getBigDecimal().multiply(k).add(ema.multiply(BigDecimal.ONE.subtract(k))).setScale(6,RoundingMode.HALF_UP);
            doubles.add(new DataVo(list.get(i).getTime(), ema));
        }
        return doubles;
    }



    public static List<DataVo> MA(List<DataVo> list, int number) {
        List<DataVo> doubles = new ArrayList<>();
        for (int i = 0; i < number; i++) {
            BigDecimal ma = CalcUtil.sumAmount(list, 0, i)
                    .divide(new BigDecimal(i + 1), 4, RoundingMode.HALF_UP);
            doubles.add(new DataVo(list.get(i).getTime(),ma));
        }
        for (int i = number; i < list.size(); i++) {
            BigDecimal divide = CalcUtil.sumAmount(list, i - number + 1, i).divide(new BigDecimal(number), 4, RoundingMode.HALF_UP);
            doubles.add(new DataVo(list.get(i).getTime(), divide));
        }
        return doubles;
    }


    public static List<DataVo> _JIAN(List<DataVo> form, List<DataVo> to) {
        if (form.size() != to.size()) {
            throw new RuntimeException("data error code 1");
        }
        List<DataVo> ret = new ArrayList<>();
        for (int i = 0; i < form.size(); i++) {
            DataVo fromVo = form.get(i);
            DataVo toVo = to.get(i);
            if (!fromVo.getTime().equals(toVo.getTime())) {
                throw new RuntimeException("jian==>time error code 1");
            }
            DataVo vo = new DataVo(fromVo.getTime(), fromVo.getBigDecimal().subtract(toVo.getBigDecimal()));
            ret.add(vo);
        }
        return ret;

    }

    public static List<DataVo> _CHENG(List<DataVo> form, int number) {

        List<DataVo> ret = new ArrayList<>();
        for (int i = 0; i < form.size(); i++) {
            DataVo fromVo = form.get(i);
            DataVo vo = new DataVo(fromVo.getTime(), fromVo.getBigDecimal().multiply(new BigDecimal(number)));
            ret.add(vo);
        }
        return ret;

    }

    public static List<DataVo> _CHU(List<DataVo> form, List<DataVo> to) {
        if (form.size() != to.size()) {
            throw new RuntimeException("data error code 1");
        }
        List<DataVo> ret = new ArrayList<>();
        for (int i = 0; i < form.size(); i++) {
            DataVo fromVo = form.get(i);
            DataVo toVo = to.get(i);
            if (!fromVo.getTime().equals(toVo.getTime())) {
                throw new RuntimeException("chu==>time error code 1");
            }
            DataVo vo = new DataVo(fromVo.getTime(), fromVo.getBigDecimal().divide(toVo.getBigDecimal(), 4, RoundingMode.HALF_UP));
            ret.add(vo);
        }
        return ret;
    }
}
